/*
    这里是 返回操作的 action  也可以在这里进行异步的请求
 */

import cookie from 'js-cookie'

import { reqRegister, reqLogin, reqBoxx, reqList, getUserList, reqGetMsgList,
    reqReceiveMsg, reqReadMsg} from '../api/index'
import {ACTION_SUCCESS, ACTION_ERROR,
    UPDATE_SUCCESS, UPDATE_ERROR,
    GET_USERLIST, GET_MSGLIST, RECEIVE_MSG,
    READMSG, LOGIN_MSGS, LOGIN_HOME
    } from './action-types'
import io from 'socket.io-client'

export const actionSuccess = (user) => ({ type: ACTION_SUCCESS, data: user})
const actionError = (msg) => ({ type: ACTION_ERROR, data:msg})
const updateSuccess = (user) => ({ type: UPDATE_SUCCESS, data:user})
export const updateError = (msg) => ({ type: UPDATE_ERROR, data:msg})

//这里是获取用户列表的同步action
const get_userlist = (userList) => ({ type: GET_USERLIST, data:userList})

//获取消息的同步action
export const getMsgList = ({ users, chatMsgs, userid}) => ({ type: GET_MSGLIST, data: { users, chatMsgs, userid}})
//此时这里接收对方的消息
export const receiveMsg= (chatMsg, userid) => ({ type: RECEIVE_MSG, data: {chatMsg, userid}})
//这里处理已读消息
export const readMsg = (from, to, count) =>({ type:READMSG, data:{ from, to, count}})

//登陆之后获取 头像信息
export const loginMsg = (users) => ({ type:LOGIN_MSGS, data:{users}})

//退出之后清除reducer的状态
export const loginHome = () =>({type:LOGIN_HOME, data:{}})

//这里是调用getUserMsgs的方法
export function accentInfo(userid){
   
    return async dispatch => {
        const response = await reqGetMsgList()
        const rel = response.data
        if (rel.code === 0){
            const { users} = rel.data
            dispatch(loginMsg(users))
        }
        
    }
}


//这里一上来就就获取用户的消息列表  登陆的时候 注册的时候 以及自动登陆的时候都要获取消息列表
async function getUserMsgs(dispatch, userid) {
    initIo(dispatch, userid)
    const response = await reqGetMsgList()

    const rel = response.data
    //分发同步action
   if (rel.code === 0){
       const { users, chatMsgs} = rel.data
       dispatch(getMsgList({ users, chatMsgs, userid}))//此时这里的结构是{users:{},chatMsgs:[]}
   }
}


//此时连接服务器的socketio在这里连接
function initIo(dispatch, userid) {
    //此时不能每次 调用一次该方法就创建一个socket 因此这里需要判断一下
    //没有就创建
    if(!io.socket){
        io.socket = io('ws://localhost:5000')

        //接收
        io.socket.on('receiveMsg',(chatMsg) =>{
            // 当退出的时候 没有userid 此时已经不需要监听receiveMsg  因为如果没有return 此时浏览器又没有刷新
            //此时这个io会一直在监听 因此这里return
            //因为现在暂时没有办法 退出的时候把 该io删除 此时只是 return掉
            if (!cookie.get('userid')){
                return
            }


            //这里是防止 同一个用户 在同一个页面 连续登陆两次 但是这个userid海一直保持
            // 第一次的userid 不知到为什么   因此这里 使用cookie里面的userid但是此时 但是通过get()方法获取到
            // 的userid是带 双引号的 因此需要通过正则表示去掉双引号 但是此时 与后台发送过来的 chatMsgs的from以及to属性数据类型不一样
            //后台的from 以及 to 是String类型
            //但是 cookie获取的是cookieString类型  通过 '==='比较出来的也不相同   因此就想到下面的方法
            /*
                此时获取到的是不带引号的userid
                提高cookie的set()方法把此useri设置成 新的cookie在 通过get()方法获取之后 数据类型就变为string
                但是此时 获取的虽然是string 但是 cookie又为它添加了一些东西 即"j:"  因此又通过正则 把j:去掉
                //之后在跟后台数据进行比较

             */
            var reg = new RegExp('"',"g");
            var reg1 = new RegExp('j:',"g");
            let useridCookie = cookie.get('userid').replace(reg, "");
            //此时应该在这里接收对方的消息 并更新状态 在两边显示
            //但是这里要过滤 因此用户只接收我发送的 和发给我的
            //此时别人发给我的 载别人那里 我就是 to
            // cookie.set('from', chatMsg.from)
            cookie.set('str', useridCookie)
            useridCookie = cookie.get('str').replace(reg1,'')
            if (chatMsg.from == useridCookie || chatMsg.to == useridCookie){
                dispatch(receiveMsg(chatMsg, userid))
            }
        })
    }
}

export const getChatMsg= ({from, to, content}) => {

    return async dispatch => {
        //此时socket不应该在发送消息的时候创建  应该在 过去消息列表的时候创建
        if (io.socket){
            io.socket.emit('sendMsg', {from, to, content})
        }
    }
}

//处理已读消息
export const hadReadMsg = ({ from, to}) =>{

    return async dispatch =>{
        const response = await reqReadMsg(to)
        const rel = response.data
        if (rel.code === 0){//成功获取
            dispatch(readMsg(from, to, rel.data))
        }
    }
}




//注册请求
export const register = (user, remin) =>{
    /*
        此时注册提交上来的数据 很多 但是 确认密码没必要提交到后台上去
        两次密码的验证 在前台验证即可
     */
    const { username, paw, pawo, type} = user
    //在这里判断 两次密码是否正确  这里是同步 action return 就会 但会一个新的 状态
    //因此不需要 dispatch
    if(!username){
        remin('用户名为空')
        return actionError('用户名为空')
    } else if(paw !== pawo){
        remin('两次密码不一样')
        return actionError('两次密码不相同')
    }

    return async dispatch =>{
        /*
        如果await关键字后面的表达式是非Promise、非thenable
        的普通的值，则会隐式调用Promise.resolve方法将其转换为Promise
        对象，await关键字会在内部调用then方法将resolve的值返回。
        总之，await关键字是then方法的语法糖，会将resolve的值传递出来。
         */
        //此时得到响应
        var response = await reqRegister({ username, paw, type})//此时确认密码没必要发到后台上去

        //此时的响应在 response的data属性中
        var rel = response.data
        //说明成功了
        if (rel.code === 0){
            getUserMsgs(dispatch, rel.data._id)
            dispatch(actionSuccess(rel.data))
        }else{//失败了
            remin(rel.msg)
            dispatch(actionError(rel.msg))
        }

    }
}
//登陆请求
export const login = (user, remin) =>{
    /*
        此时注册提交上来的数据 很多 但是 确认密码没必要提交到后台上去
        两次密码的验证 在前台验证即可
     */
    const { username, paw} = user
    //在这里判断 两次密码是否正确  这里是同步 action return 就会 但会一个新的 状态
    //因此不需要 dispatch
    if(!username){
        remin('用户名为空')
        return actionError('用户名为空')
    }else if(!paw){
        remin('请输入密码')
        return actionError('请输入密码')
    }
    return async dispatch =>{
        /*
        如果await关键字后面的表达式是非Promise、非thenable
        的普通的值，则会隐式调用Promise.resolve方法将其转换为Promise
        对象，await关键字会在内部调用then方法将resolve的值返回。
        总之，await关键字是then方法的语法糖，会将resolve的值传递出来。
         */
        //此时得到响应
        var response = await reqLogin({ username, paw})//此时确认密码没必要发到后台上去

        //此时的响应在 response的data属性中
        var rel = response.data
        //说明成功了
        if (rel.code === 0){
            //获取用户的聊天信息
            // getUserMsgs(dispatch, rel.data._id)
            dispatch(actionSuccess(rel.data))
        }else{//失败了
            remin(rel.msg)
            dispatch(actionError(rel.msg))
        }

    }
}
//老板的更新信息请求
export const updateBoox = (user, remin) =>{
    const {header, post, info, company, salary} = user
    if(!header){
        remin('请选择头像')
        return actionError('请选择头像')
    }else if(!post){
        remin('请输入您的职位')
        return actionError('请输入您的职位')
    }else if(!company){
        remin('请输入您的公司')
        return actionError('请输入您的公司')
    }else if(!salary){
        remin('请输入薪资')
        return actionError('请输入薪资')
    }else if(!info){
        remin('职位的描述')
        return actionError('职位的描述')
    }

    return async dispatch =>{
        //此时得到响应
        var response = await reqBoxx(user)//数据的提交  全部

        //此时的响应在 response的data属性中
        var rel = response.data
        //说明成功了
        if (rel.code === 0){

            // getUserMsgs(dispatch, rel.data._id)
            //获取用户的聊天信息
            dispatch(updateSuccess(rel.data))
        }else{//失败了
            remin(rel.msg)
            dispatch(updateError(rel.msg))
        }
    }
}

//大神的更新信息请求
export const updateManito = (user, remin) =>{
    const {header, post, info} = user
    if(!header){
        remin('请选择头像')
        return actionError('请选择头像')
    }else if(!post){
        remin('请输入您的职位')
        return actionError('请输入您的职位')
    }else if(!info){
        remin('职位的描述')
        return actionError('职位的描述')
    }

    return async dispatch =>{
        //此时得到响应
        var response = await reqBoxx(user)//数据的提交  全部

        //此时的响应在 response的data属性中
        var rel = response.data
        //说明成功了
        if (rel.code === 0){
            //此时在这里也要发送请求  更新头像
            // getUserMsgs(dispatch, rel.data._id)

            dispatch(updateSuccess(rel.data))
        }else{//失败了
            remin(rel.msg)
            dispatch(updateError(rel.msg))
        }
    }
}

//这里是实现 自动登陆 发送ajax拿数据显示相应的列表
export const updateList= () => {
    return async dispatch => {
        const response = await reqList()
        const rel = response.data
        //  拿到相应  提示信息
        if (rel.code === 0){
            //获取用户的聊天信息
            getUserMsgs(dispatch, rel.data._id)
            //返回相应的数据  显示相应的列表
            dispatch(updateSuccess(rel.data))
        } else{
            //失败了  提示相应的 语句
            //前往登陆页面
            dispatch(updateError(rel.data))
        }
    }
}

//这里是异步获取用户列表的操作
export const updateUserList= (type) => {
    return async dispatch => {
        const response = await getUserList(type)
        const rel = response.data
        //  拿到相应  提示信息
        if (rel.code === 0){
            //返回相应的数据  显示相应的列表
            dispatch(get_userlist(rel.data))
        } else{
            dispatch(actionError('没有数据'))
        }
    }
}

